package net.vinote.smart.platform.service.servlet;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.vinote.smart.platform.comm.DateFunction;
import net.vinote.smart.platform.comm.PlatformConst;
import net.vinote.smart.platform.comm.StringFunction;
import net.vinote.smart.platform.module.database.BeanEntityFactory;
import net.vinote.smart.platform.module.database.DBManager;
import net.vinote.smart.platform.module.database.DBManagerFactory;
import net.vinote.smart.platform.module.database.bo.BizObject;
import net.vinote.smart.platform.service.GeneralTools;
import net.vinote.smart.platform.service.SRE;
import net.vinote.smart.platform.service.action.AppInfoAction;
import net.vinote.smart.platform.service.action.AppItemAction;
import net.vinote.smart.platform.service.action.UserInfoAction;
import net.vinote.smart.platform.service.bean.AppInfo;
import net.vinote.smart.platform.service.bean.AppItem;
import net.vinote.smart.platform.service.bean.CodeLibrary;
import net.vinote.smart.platform.service.bean.User;
import net.vinote.smart.platform.service.bean.UserInfo;
import net.vinote.smart.platform.service.util.OnlineUserPool;
import net.vinote.smart.platform.service.util.ResultCode;

public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = -81362236220158709L;

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		HttpSession session = req.getSession();
		String userID = req.getParameter("userid");
		String password = req.getParameter("password");
		boolean isSafeLogin = PlatformConst.Yes == SRE.getSystemParameter()
				.getSafeLogin();
		// 是否为cookie的自动登录
		boolean isCookie = false;
		Cookie[] cookies = req.getCookies();
		if (cookies != null) {
			for (Cookie c : req.getCookies()) {
				if (c.getName().equals("autoLogin")
						&& PlatformConst.YES.equals(c.getValue())) {
					isCookie = true;
				}
			}
		}
		// 是否启用验证码登录
		if (!isCookie
				&& PlatformConst.Yes == SRE.getSystemParameter()
						.getVerifyCode()) {
			String verifyCode = req.getParameter("verifyCode");
			String sessionVerify = session.getAttribute("verifyCode")
					.toString();
			if (sessionVerify == null || !sessionVerify.equals(verifyCode)) {
				session.setAttribute(ResultCode.MESSAGE, "验证码错误!");
				resp.sendRedirect("login.jsp");
				return;
			}
		}

		UserInfoAction action = new UserInfoAction();
		DBManager bm = DBManagerFactory.getInstance("user_info");
		int state = ResultCode.USER_CORRECT;
		BizObject bo = null;
		UserInfo userInfo = new UserInfo();
		try {
			bo = bm.createQuery(SRE.getTable("user_info").getFieldsName(),
					"userid=?").setParamVal(userID).getSingleResult();

		} catch (SQLException e) {
			e.printStackTrace();
		}
		if (bo == null) {
			state = ResultCode.USER_NOT_EXISTS;
		} else {
			BeanEntityFactory.getInstance().getObject(userInfo, bo);
			state = userInfo.getPassword().equals(
					GeneralTools.encrypt(password,
							GeneralTools.getAesKey(userID))) ? ResultCode.USER_CORRECT
					: ResultCode.PASSWORD_ERROR;
			// 是否启用了安全登录功能
			if (isSafeLogin) {
				long lastTime = DateFunction.getTime(StringFunction
						.nullToBlank(userInfo.getLastLoginTime()));
				if (System.currentTimeMillis() - lastTime < SRE
						.getSystemParameter().getLockTime()
						* PlatformConst.TimeConstant.ONE_MINUTE
						&& SRE.getSystemParameter().getLoginFailTimes() <= userInfo
								.getLoginError()) {
					session.setAttribute(ResultCode.MESSAGE, "账户已锁定,无法登录!");
					resp.sendRedirect("login.jsp");
					return;
				}
			}

		}
		if (ResultCode.USER_CORRECT == state) {
			// 清理登录失败计数
			if (userInfo.getLoginError() > 0) {
				bo.setAttribute("loginerror", "0");
			}
			try {
				bo.setAttribute("lastLoginTime", DateFunction.getCurrentTime());
				bm.updateBizObject(bo);
			} catch (SQLException e) {
				e.printStackTrace();
			}

			// 是否启用自动登录功能,启用之后记录cookie
			if (PlatformConst.Yes == SRE.getSystemParameter().getAutoLogin()) {
				int oneMonth = 60 * 60 * 24 * 31;
				String recodePwd = req.getParameter("recodePwd");
				String autoLogin = req.getParameter("autoLogin");
				if (PlatformConst.YES.equals(recodePwd)) {
					Cookie recodePwdCookie = new Cookie("recodePwd", recodePwd);
					recodePwdCookie.setMaxAge(oneMonth);
					Cookie loginCookie = new Cookie("autoLogin", autoLogin);
					loginCookie.setMaxAge(oneMonth);
					Cookie userCookie = new Cookie("u&p",
							GeneralTools.encrypt(userID + " " + password));
					userCookie.setMaxAge(oneMonth);
					resp.addCookie(recodePwdCookie);
					resp.addCookie(loginCookie);
					resp.addCookie(userCookie);
				}
			}
			User user = new User(userInfo);
			initUserCache(user);
			session.setAttribute("user", user);
			// 若启用的单会话登录，则使其他该user的会话失效
			if (SRE.getSystemParameter().getSingleSessionLogin() == PlatformConst.Yes) {
				OnlineUserPool.getInstance().setUserSession(userID, session);
			}
			user.setRoleID(action.getUserRoles(userID));
			resp.sendRedirect("frame/main_page.jsp");
		} else {
			session.setAttribute(ResultCode.MESSAGE, "密码错误!");
			resp.sendRedirect("login.jsp");

			if (isSafeLogin && ResultCode.USER_NOT_EXISTS != state) {
				try {
					bo.setAttribute("loginerror",
							String.valueOf(userInfo.getLoginError() + 1));
					bo.setAttribute("lastLoginTime",
							DateFunction.getCurrentTime());
					bm.updateBizObject(bo);
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			// 登录失败删除cookie
			if (cookies != null) {
				for (Cookie c : cookies) {
					if (c.getName().equals("recodePwd")
							|| c.getName().equals("autoLogin")
							|| c.getName().equals("userid")
							|| c.getName().equals("password")) {
						c.setMaxAge(0);
					}
				}
			}
		}

	}

	/**
	 * 对于用户会话期间需要的数据进行缓存
	 * 
	 * @param user
	 * @throws SQLException
	 */
	private void initUserCache(User user) {
		try {
			String userId = user.getUserID();
			// 第一步:加载用户可用的科目列表
			AppInfoAction appInfoAction = new AppInfoAction();
			appInfoAction.setUserID(userId);
			List<CodeLibrary> subjectList = appInfoAction
					.getAppInfoSubjectList();
			user.setSubjectList(subjectList);

			// 第二步:获取当前用户可科目下可用的应用信息
			AppItemAction itemAction = new AppItemAction();
			for (CodeLibrary curSubject : subjectList) {
				List<AppInfo> infoList = appInfoAction
						.getAppsByUserIdAndSubject(userId,
								curSubject.getItemNo());
				user.setAppInfoList(curSubject.getItemNo(), infoList);

				// 第三步:加载当前用户应用下可用的栏目
				for (AppInfo appInfo : infoList) {
					List<AppItem> itemList = itemAction.getAppItemsByUserRoles(
							appInfo.getAppID(), userId);
					user.setAppItemList(appInfo.getAppID(), itemList);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}

}
